package com.lanchetech.merchant.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.lanchetech.bean.request.ActivityReq;
import com.lanchetech.bean.response.BasePageResp;
import com.lanchetech.bean.response.BaseResp;
import com.lanchetech.bean.response.ResultData;
import com.lanchetech.bean.util.PageHelpUtil;
import com.lanchetech.bean.vo.ActivityVo;
import com.lanchetech.common.constants.BaseConstant;
import com.lanchetech.common.enums.ActivityEnum;
import com.lanchetech.common.enums.ResultCode;
import com.lanchetech.common.exception.ResultCodeException;
import com.lanchetech.dao.ActivityMapper;
import com.lanchetech.dao.SkuMapper;
import com.lanchetech.entity.Activity;
import com.lanchetech.entity.ActivityBindSpu;
import com.lanchetech.entity.Merchant;
import com.lanchetech.entity.Sku;
import com.lanchetech.merchant.service.ActivityBindSpuService;
import com.lanchetech.merchant.service.ActivityService;
import jodd.util.StringUtil;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

@Service
public class ActivityServiceImpl extends ServiceImpl<ActivityMapper, Activity> implements ActivityService {

    @Resource
    private ActivityBindSpuService bindSpuService;
    @Resource
    private SkuMapper skuMapper;


    @Override
    public ResultData<BasePageResp<ActivityVo>> getPage(ActivityReq req) {
        Page page = PageHelper.startPage(req.getPageNo(), req.getPageSize());
        Merchant merchant = (Merchant) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        List<Activity> list = list(new LambdaQueryWrapper<Activity>().eq(Activity::getTenantId, merchant.getTenantId())
                .eq(Activity::getIsDeleted, BaseConstant.ZERO)
                .eq(Objects.nonNull(req.getId()), Activity::getId, req.getId())
                .like(StringUtil.isNotBlank(req.getName()), Activity::getName, req.getName())
                .eq(Objects.nonNull(req.getAuditStatus()), Activity::getAuditStatus, req.getAuditStatus())
                .last("ORDER BY FIELD(status, 1) DESC , created_at DESC"));
        List<ActivityVo> activityVos = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(list)) {
            list.forEach(s -> {
                ActivityVo activityVo = new ActivityVo();
                BeanUtils.copyProperties(s, activityVo);
                activityVo.setTypeDesc(ActivityEnum.getRemarkByActivity(s.getType()));
                activityVos.add(activityVo);
            });
        }
        return PageHelpUtil.buildPage(activityVos, page);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void editActivity(ActivityVo activityVo) throws Exception {
        Activity activity = new Activity();
        BeanUtils.copyProperties(activityVo, activity);
        if (CollectionUtils.isNotEmpty(activityVo.getBindSpus())) {
            // 校验绑定活动商品定义的 活动库存是否小于原本库存
            List<Sku> allByIds = skuMapper.findAllByIds(activityVo.getBindSpus().stream().map(ActivityBindSpu::getSkuId).collect(Collectors.toList()));
            Map<Long, Sku> stockMap = allByIds.stream().collect(Collectors.toMap(Sku::getId, s -> s, (v1, v2) -> v1));
            for (ActivityBindSpu spus : activityVo.getBindSpus()) {
                if (spus.getActivityStock() < BaseConstant.ZERO) {
                    String format = String.format(ResultCode.ACTIVITY_STOCK_ERROR2.getMsg(), stockMap.get(spus.getSkuId()).getSpuId());
                    throw new Exception(format);
                }
                if (spus.getActivityStock() > stockMap.get(spus.getSkuId()).getStock()) {
                    String format = String.format(ResultCode.ACTIVITY_STOCK_ERROR.getMsg(), stockMap.get(spus.getSkuId()).getSpuId());
                    throw new Exception(format);
                }
            }
        }
        Merchant merchant = (Merchant) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        if (Objects.isNull(activityVo.getId())) {
            // 设置新人专区活动 然后活动审核为未审核
            activity.setType(ActivityEnum.NEW_USER.getActivity());
            save(activity);
            List<ActivityBindSpu> bindSpus = activityVo.getBindSpus();
            // 新增绑定商品
            if (CollectionUtils.isNotEmpty(bindSpus)) {
                bindSpus.forEach(s -> s.setActivityId(activity.getId()));
                bindSpuService.saveBatch(bindSpus);
            }
        } else {
            // 如果开启活动 检查是否有已经开启的新人活动 如果有则不能开启
            if (activityVo.getStatus().equals(BaseConstant.ONE)) {
                List<Activity> list = list(new LambdaQueryWrapper<Activity>().eq(Activity::getTenantId, merchant.getTenantId())
                        .eq(Activity::getStatus, BaseConstant.ONE)
                        .ne(Activity::getId, activityVo.getId())
                        .eq(Activity::getIsDeleted, BaseConstant.ZERO));
                if (list.size() > BaseConstant.ZERO) {
                    throw new ResultCodeException(ResultCode.ACTIVITY_STATUS_OPEN);
                }
            }


            List<ActivityBindSpu> bindSpus = activityVo.getBindSpus();
            // 检查需要新增 更新 删除的商品信息
            List<ActivityBindSpu> list = bindSpuService.list(new LambdaQueryWrapper<ActivityBindSpu>().eq(ActivityBindSpu::getActivityId, activity.getId())
                    .eq(ActivityBindSpu::getIsDeleted, BaseConstant.ZERO));
            if (CollectionUtils.isNotEmpty(list)) {
                // 现在有 修改后没有的 都要删掉
                List<Long> longs = list.stream().map(ActivityBindSpu::getId).filter(id -> !bindSpus.stream().map(ActivityBindSpu::getId).collect(Collectors.toList()).contains(id)).collect(Collectors.toList());
                if (longs.size() > BaseConstant.ZERO) {
                    boolean update = bindSpuService.lambdaUpdate().in(ActivityBindSpu::getId, longs).set(ActivityBindSpu::getIsDeleted, BaseConstant.ONE).update();
                }
            }
            if (CollectionUtils.isNotEmpty(bindSpus)) {
                bindSpus.forEach(s -> s.setActivityId(activity.getId()));
                // 如果有新添加的商品 活动状态重新变为未审核 活动状态变更为关闭状态
                List<ActivityBindSpu> newSkus = bindSpus.stream().filter(s -> Objects.isNull(s.getId())).collect(Collectors.toList());
                if (newSkus.size() > BaseConstant.ZERO) {
                    activity.setStatus(BaseConstant.ZERO);
                    activity.setAuditStatus(BaseConstant.ZERO);
                    // 如果已拒绝的活动重新提交 置空拒绝原因
                    if (BaseConstant.TWO.equals(activityVo.getAuditStatus())) {
                        activity.setRefuseCause(null);
                    }
                }
                bindSpuService.saveOrUpdateBatch(bindSpus);
            }
            updateById(activity);
        }
    }


    @Override
    public BaseResp deleteActivity(Long id) {
        Activity byId = getById(id);
        if (Objects.isNull(byId)){
            return new BaseResp(ResultCode.ACTIVITY_IS_NULL);
        }
        byId.setIsDeleted(BaseConstant.ONE);
        updateById(byId);
        return new BaseResp();
    }

    @Override
    public ResultData<ActivityVo> getDetail(Long id) {
        ActivityVo vo = new ActivityVo();
        Activity byId = getById(id);
        if (Objects.nonNull(byId)){
            BeanUtils.copyProperties(byId, vo);
            vo.setTypeDesc(ActivityEnum.getRemarkByActivity(byId.getType()));
        }
        return new ResultData<>(vo);
    }

    @Override
    public BaseResp onOrOffStatus(Long id) {
        Activity activity = getById(id);
        Merchant merchant = (Merchant) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        // 不是审核通过状态 不能操作
        if (!activity.getAuditStatus().equals(BaseConstant.ONE)){
            return new BaseResp(ResultCode.ACTIVITY_AUDIT_STATUS);
        }
        if (BaseConstant.ZERO.equals(activity.getStatus())) {
            // 查询是否有正在开启状态的活动
            List<Activity> list = list(new LambdaQueryWrapper<Activity>().eq(Activity::getTenantId, merchant.getTenantId())
                    .eq(Activity::getStatus, BaseConstant.ONE)
                    .ne(Activity::getId, id)
                    .eq(Activity::getIsDeleted, BaseConstant.ZERO));
            if (list.size() > BaseConstant.ZERO) {
                return new BaseResp(ResultCode.ACTIVITY_STATUS_OPEN);
            }
            activity.setStatus(BaseConstant.ONE);
        } else {
            activity.setStatus(BaseConstant.ZERO);
        }
        updateById(activity);
        return new BaseResp();
    }
}
